package com.copyctrl.campus.portal.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.copyctrl.campus.common.constant.MapperConstant;
import com.copyctrl.campus.common.constant.RedisConstant;
import com.copyctrl.campus.common.constant.RedisKind;
import com.copyctrl.campus.common.domain.MysqlData;
import com.copyctrl.campus.common.domain.RedisData;
import com.copyctrl.campus.common.domain.SendData;
import com.copyctrl.campus.common.domain.User;
import com.copyctrl.campus.portal.dto.CommentDTO;
import com.copyctrl.campus.portal.service.CommentService;
import com.copyctrl.campus.portal.service.DynamicService;
import com.copyctrl.campus.portal.service.UserService;
import com.copyctrl.mapper.CampCommentMapper;
import com.copyctrl.model.CampComment;
import com.copyctrl.model.CampCommentExample;
import com.copyctrl.publisher.send.DataPublisher;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author:JH
 * @version:1.0
 * 已整合redis以及rabbitmq
 * type:0是文章，1是动态
 */
@Service
@Slf4j
public class CommentServiceImpl implements CommentService {

    @Autowired
    CampCommentMapper campCommentMapper;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    UserService userService;

    @Autowired
    DataPublisher dataPublisher;

    @Autowired
    DynamicService dynamicService;

    @Override
    public int addComment(CampComment comment) {
        int insert = campCommentMapper.insert(comment);
        if (insert == 1) {
            //这里使用的是多线程实现异步存储
            execute(comment);
        }
        return insert;
    }

    @Override
    public List<CommentDTO> findByTextId(Integer id,Integer type) {
        String key;
        if(type==0){
             key=RedisConstant.COMMENT_KEY+id;
        }else {
             key= RedisConstant.COMMENT_DYNAMIC+id;
        }
        Map<Object, Object> entries = redisTemplate.opsForHash().entries(key);
        //评论数为0，从数据库中查，查不到返回空
        if (entries.size()<1) {
            CampCommentExample example = new CampCommentExample();
            example.createCriteria().andTextIdEqualTo(id).andTypeEqualTo(type);
            entries = campCommentMapper.selectByExampleWithBLOBs(example).stream()
                    .collect(Collectors.toMap(CampComment::getId, comment -> JSONUtil.toJsonStr(comment)));
            //异步存入redis
            RedisData<CommentDTO> redisData = RedisData.getRedisDataMap( RedisKind.HASH, entries, "putAll",key);
            SendData data = new SendData();
            data.setRedisData(redisData);
            data.setDataType(true);
            dataPublisher.redisData(JSONUtil.toJsonStr(data));
        }
        List<CommentDTO> list=new ArrayList<>();
        for (Object commentKey : entries.keySet()) {
            CampComment comment = JSONUtil.toBean(entries.get(commentKey).toString(), CampComment.class);
            String openid = comment.getUser();
            String s = redisTemplate.opsForValue().get(RedisConstant.USER_KEY + openid);
            User user = JSONUtil.toBean(s, User.class);
            CommentDTO commentDTO = BeanUtil.copyProperties(comment, CommentDTO.class);
            commentDTO.setUserInfo(user);
            String puser = comment.getPuser();
            if(!StrUtil.isBlank(puser)){
                String s2 = redisTemplate.opsForHash().get(RedisConstant.ID_OPENID, puser).toString();
                String s1 = redisTemplate.opsForValue().get(RedisConstant.USER_KEY + s2);
                User user1 = JSONUtil.toBean(s1, User.class);
                commentDTO.setPUserInfo(user1);
                commentDTO.setPuser(null);
            }
            commentDTO.setUser(null);
            list.add(commentDTO);
        }
        return list;
    }

    @Override
    public Long deleteByCommentId(Integer id, Integer textId,Integer type) {
        String key;
        if(type==0){
            key=RedisConstant.COMMENT_KEY+textId;
        }else {
            key= RedisConstant.COMMENT_DYNAMIC+textId;
        }
        //先删除redis中的数据，删除成功后就返回，异步删除mysql中的数据，减少用户等待时间
        Long i = redisTemplate.opsForHash().delete(key, id.toString());
        //异步
        if (i == 1) {
            MysqlData<Integer> mysqlData = new MysqlData<>();
            mysqlData.setData(id);
            mysqlData.setMethod("deleteByPrimaryKey");
            mysqlData.setMapperConstantName(MapperConstant.Comment);
            SendData data = new SendData();
            data.setMysqlData(mysqlData);
            data.setDataType(false);
            dataPublisher.mysqlData(JSONUtil.toJsonStr(data));
        }
        return i;
    }

    @Override
    public int deleteByTextId(Integer id,Integer type) {
        String key;
        if(type==0){
            key=RedisConstant.COMMENT_KEY+id;
        }else {
            key= RedisConstant.COMMENT_DYNAMIC+id;
        }
        redisTemplate.delete(key);
        CampCommentExample example = new CampCommentExample();
        example.createCriteria().andTextIdEqualTo(id).andTypeEqualTo(type);
        int i = campCommentMapper.deleteByExample(example);
        return i;
    }

    /**
     * 异步插入reids
     */
    @Async("defaultThreadPoolExecutor")
    public void execute(CampComment comment) {
        String key;
        if(comment.getType()==0){
            key=RedisConstant.COMMENT_KEY+comment.getTextId();
        }else {
            key= RedisConstant.COMMENT_DYNAMIC+comment.getTextId();
        }
        //修改存储逻辑，再取出评论时做映射操作
//        String userId = comment.getUser();
//        CommentDTO commentDTO = new CommentDTO();
//        BeanUtil.copyProperties(comment, commentDTO, false);
//        User user = JSONUtil.toBean(redisTemplate.opsForValue().get(RedisConstant.USER_KEY + userId), User.class);
//        commentDTO.setUser(null);
//        commentDTO.setUserInfo(user);
//        if (comment.getPid()!=null) {
//            String pUserOpenid = redisTemplate.opsForHash().entries(RedisConstant.ID_OPENID).get(comment.getPuser()).toString();
//            User user1 = JSONUtil.toBean(redisTemplate.opsForValue().get(RedisConstant.USER_KEY + pUserOpenid), User.class);
//            commentDTO.setPUserInfo(user1);
//        }
        redisTemplate.opsForHash().put(key, comment.getId().toString(), JSONUtil.toJsonStr(comment));
    }
}
